using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Text.RegularExpressions;
using Microsoft.Extensions.Logging;
using Volo.Abp.DependencyInjection;

namespace MatrixFramework.Shared.Application.Maintenance
{
    /// <summary>
    /// 代码重构助手
    /// </summary>
    public class CodeRefactoringHelper : ITransientDependency
    {
        private readonly ILogger<CodeRefactoringHelper> _logger;

        public CodeRefactoringHelper(ILogger<CodeRefactoringHelper> logger)
        {
            _logger = logger;
        }

        /// <summary>
        /// 分析代码并提供重构建议
        /// </summary>
        public RefactoringReport AnalyzeCode(string filePath)
        {
            if (!File.Exists(filePath))
            {
                throw new FileNotFoundException($"文件不存在: {filePath}");
            }

            var content = File.ReadAllText(filePath);
            var report = new RefactoringReport
            {
                FilePath = filePath,
                FileName = Path.GetFileName(filePath),
                AnalysisTime = DateTime.UtcNow
            };

            try
            {
                // 分析长方法
                AnalyzeLongMethods(content, report);

                // 分析复杂条件
                AnalyzeComplexConditions(content, report);

                // 分析重复代码
                AnalyzeDuplicateCode(content, report);

                // 分析魔法数字
                AnalyzeMagicNumbers(content, report);

                // 分析异常处理
                AnalyzeExceptionHandling(content, report);

                // 分析命名规范
                AnalyzeNamingIssues(content, report);

                // 计算重构优先级
                CalculateRefactoringPriority(report);

                _logger.LogInformation("代码重构分析完成: {File}, 建议: {Count}", filePath, report.Suggestions.Count);
            }
            catch (Exception ex)
            {
                _logger.LogError(ex, "分析文件 {File} 时发生错误", filePath);
                report.Errors.Add($"分析失败: {ex.Message}");
            }

            return report;
        }

        /// <summary>
        /// 自动重构代码
        /// </summary>
        public RefactoringResult AutoRefactor(string filePath, RefactoringOptions options)
        {
            if (!File.Exists(filePath))
            {
                throw new FileNotFoundException($"文件不存在: {filePath}");
            }

            var originalContent = File.ReadAllText(filePath);
            var refactoredContent = originalContent;
            var result = new RefactoringResult
            {
                FilePath = filePath,
                OriginalContent = originalContent,
                Changes = new List<RefactoringChange>()
            };

            try
            {
                // 备份原文件
                if (options.CreateBackup)
                {
                    var backupPath = filePath + ".backup";
                    File.WriteAllText(backupPath, originalContent);
                    result.Changes.Add(new RefactoringChange
                    {
                        Type = RefactoringType.Backup,
                        Description = "创建原文件备份",
                        FilePath = backupPath
                    });
                }

                // 应用重构规则
                if (options.FixNamingConventions)
                {
                    refactoredContent = ApplyNamingConventions(refactoredContent, result);
                }

                if (options.OrganizeImports)
                {
                    refactoredContent = OrganizeImports(refactoredContent, result);
                }

                if (options.FixMagicNumbers)
                {
                    refactoredContent = FixMagicNumbers(refactoredContent, result);
                }

                if (options.ImproveExceptionHandling)
                {
                    refactoredContent = ImproveExceptionHandling(refactoredContent, result);
                }

                if (options.OptimizeStringOperations)
                {
                    refactoredContent = OptimizeStringOperations(refactoredContent, result);
                }

                // 写入重构后的内容
                if (refactoredContent != originalContent)
                {
                    File.WriteAllText(filePath, refactoredContent);
                    result.RefactoredContent = refactoredContent;
                    result.Success = true;
                }
                else
                {
                    result.Success = false;
                    result.Message = "没有发现需要重构的内容";
                }

                _logger.LogInformation("代码重构完成: {File}, 变更: {Count}", filePath, result.Changes.Count);
            }
            catch (Exception ex)
            {
                _logger.LogError(ex, "重构文件 {File} 时发生错误", filePath);
                result.Success = false;
                result.Message = $"重构失败: {ex.Message}";
            }

            return result;
        }

        /// <summary>
        /// 生成重构报告
        /// </summary>
        public string GenerateRefactoringReport(RefactoringReport report)
        {
            var reportBuilder = new System.Text.StringBuilder();

            reportBuilder.AppendLine("# 代码重构报告");
            reportBuilder.AppendLine();
            reportBuilder.AppendLine($"**文件**: {report.FileName}");
            reportBuilder.AppendLine($"**分析时间**: {report.AnalysisTime:yyyy-MM-dd HH:mm:ss}");
            reportBuilder.AppendLine($"**总体评分**: {report.OverallScore:F1}/10");
            reportBuilder.AppendLine();

            if (report.Suggestions.Any())
            {
                reportBuilder.AppendLine("## 重构建议");
                reportBuilder.AppendLine();

                var groupedSuggestions = report.Suggestions.GroupBy(s => s.Type).OrderBy(g => g.Key);
                foreach (var group in groupedSuggestions)
                {
                    reportBuilder.AppendLine($"### {GetRefactoringTypeName(group.Key)}");
                    reportBuilder.AppendLine();

                    foreach (var suggestion in group.OrderByDescending(s => s.Priority))
                    {
                        reportBuilder.AppendLine($"- **[优先级: {suggestion.Priority}]** {suggestion.Message}");
                        if (!string.IsNullOrEmpty(suggestion.Description))
                        {
                            reportBuilder.AppendLine($"  - {suggestion.Description}");
                        }
                        if (suggestion.LineNumber > 0)
                        {
                            reportBuilder.AppendLine($"  - 位置: 第 {suggestion.LineNumber} 行");
                        }
                        reportBuilder.AppendLine();
                    }
                }
            }

            if (report.Issues.Any())
            {
                reportBuilder.AppendLine("## 代码问题");
                reportBuilder.AppendLine();

                foreach (var issue in report.Issues)
                {
                    reportBuilder.AppendLine($"- **[{issue.Severity}]** {issue.Message}");
                    if (issue.LineNumber > 0)
                    {
                        reportBuilder.AppendLine($"  - 位置: 第 {issue.LineNumber} 行");
                    }
                    reportBuilder.AppendLine();
                }
            }

            if (report.Metrics.Any())
            {
                reportBuilder.AppendLine("## 代码指标");
                reportBuilder.AppendLine();

                foreach (var metric in report.Metrics)
                {
                    reportBuilder.AppendLine($"- **{metric.Name}**: {metric.Value}");
                }
                reportBuilder.AppendLine();
            }

            return reportBuilder.ToString();
        }

        private void AnalyzeLongMethods(string content, RefactoringReport report)
        {
            var methodPattern = @"(?:public|private|protected|internal)\s+(?:static\s+)?(?:async\s+)?\w+\s*\(.*?\)\s*\{";
            var methodMatches = Regex.Matches(content, methodPattern);

            foreach (Match match in methodMatches)
            {
                var methodStart = match.Index;
                var methodContent = ExtractMethodContent(content, methodStart);

                if (methodContent != null)
                {
                    var lineCount = methodContent.Split('\n').Length;
                    if (lineCount > 50)
                    {
                        report.Suggestions.Add(new RefactoringSuggestion
                        {
                            Type = RefactoringType.ExtractMethod,
                            Message = $"方法过长 ({lineCount} 行)，建议拆分为更小的方法",
                            Description = "长方法难以理解和维护，建议将复杂逻辑提取为独立的方法",
                            Priority = lineCount > 100 ? RefactoringPriority.High : RefactoringPriority.Medium,
                            LineNumber = content.Substring(0, methodStart).Count(c => c == '\n') + 1
                        });
                    }
                }
            }
        }

        private void AnalyzeComplexConditions(string content, RefactoringReport report)
        {
            var complexConditionPattern = @"(if\s*\([^)]{20,}\})|(if\s*\([^)]*\)\s*\{\s*if\s*\()";
            var matches = Regex.Matches(content, complexConditionPattern);

            foreach (Match match in matches)
            {
                report.Suggestions.Add(new RefactoringSuggestion
                {
                    Type = RefactoringType.ExtractMethod,
                    Message = "条件表达式过于复杂，建议提取为独立的方法或变量",
                    Description = "复杂的条件表达式难以理解和维护，建议将逻辑提取为有意义的方法名",
                    Priority = RefactoringPriority.Medium,
                    LineNumber = content.Substring(0, match.Index).Count(c => c == '\n') + 1
                });
            }
        }

        private void AnalyzeDuplicateCode(string content, RefactoringReport report)
        {
            var lines = content.Split('\n');
            var lineGroups = lines
                .Where(line => !string.IsNullOrWhiteSpace(line) && !line.Trim().StartsWith("//"))
                .GroupBy(line => line.Trim())
                .Where(g => g.Count() > 2)
                .OrderByDescending(g => g.Count());

            foreach (var group in lineGroups.Take(5)) // 只显示前5个重复最多的
            {
                report.Suggestions.Add(new RefactoringSuggestion
                {
                    Type = RefactoringType.ExtractMethod,
                    Message = $"发现重复代码段 (重复 {group.Count()} 次)",
                    Description = "重复代码增加了维护成本，建议提取为共享方法",
                    Priority = RefactoringPriority.Low,
                    LineNumber = Array.FindIndex(lines, line => line.Contains(group.Key)) + 1
                });
            }
        }

        private void AnalyzeMagicNumbers(string content, RefactoringReport report)
        {
            var magicNumberPattern = @"(?<![\w.])\b(0|[1-9]\d*)\b(?![\w.])";
            var matches = Regex.Matches(content, magicNumberPattern);

            var magicNumbers = matches
                .Select(m => int.Parse(m.Value))
                .Where(n => n != 0 && n != 1 && n != -1)
                .GroupBy(n => n)
                .Where(g => g.Count() >= 2)
                .OrderByDescending(g => g.Key);

            foreach (var group in magicNumbers.Take(10))
            {
                report.Suggestions.Add(new RefactoringSuggestion
                {
                    Type = RefactoringType.ExtractConstant,
                    Message = $"发现魔法数字 {group.Key} (使用 {group.Count()} 次)",
                    Description = "魔法数字降低了代码可读性，建议定义为命名常量",
                    Priority = RefactoringPriority.Low,
                    LineNumber = 0 // 魔法数字通常有多处使用，不指定具体行号
                });
            }
        }

        private void AnalyzeExceptionHandling(string content, RefactoringReport report)
        {
            // 检查空的catch块
            var emptyCatchPattern = @"catch\s*\([^)]*\)\s*\{\s*\}";
            var emptyCatchMatches = Regex.Matches(content, emptyCatchPattern);

            foreach (Match match in emptyCatchMatches)
            {
                report.Issues.Add(new CodeIssue
                {
                    Severity = IssueSeverity.Warning,
                    Message = "发现空的catch块，应该至少记录日志或重新抛出异常",
                    LineNumber = content.Substring(0, match.Index).Count(c => c == '\n') + 1
                });
            }

            // 检查catch (Exception ex)但没有使用ex
            var unusedExceptionPattern = @"catch\s*\(\s*Exception\s+(\w+)\s*\)\s*\{(?![^{]*?\1[^{]*?)";
            var unusedExceptionMatches = Regex.Matches(content, unusedExceptionPattern);

            foreach (Match match in unusedExceptionMatches)
            {
                report.Issues.Add(new CodeIssue
                {
                    Severity = IssueSeverity.Info,
                    Message = "捕获了异常但未使用，建议处理异常或使用通配符catch",
                    LineNumber = content.Substring(0, match.Index).Count(c => c == '\n') + 1
                });
            }
        }

        private void AnalyzeNamingIssues(string content, RefactoringReport report)
        {
            // 检查单字母变量名
            var singleVariablePattern = @"(?:var|const)\s+([a-z])\s*[=;]";
            var singleVariableMatches = Regex.Matches(content, singleVariablePattern);

            foreach (Match match in singleVariableMatches)
            {
                var variableName = match.Groups[1].Value;
                if (!IsAcceptableSingleLetterVariable(variableName))
                {
                    report.Issues.Add(new CodeIssue
                    {
                        Severity = IssueSeverity.Info,
                        Message = $"单字母变量名 '{variableName}' 缺乏描述性",
                        LineNumber = content.Substring(0, match.Index).Count(c => c == '\n') + 1
                    });
                }
            }
        }

        private void CalculateRefactoringPriority(RefactoringReport report)
        {
            report.OverallScore = 10.0;

            // 根据建议优先级扣分
            foreach (var suggestion in report.Suggestions)
            {
                switch (suggestion.Priority)
                {
                    case RefactoringPriority.High:
                        report.OverallScore -= 1.0;
                        break;
                    case RefactoringPriority.Medium:
                        report.OverallScore -= 0.5;
                        break;
                    case RefactoringPriority.Low:
                        report.OverallScore -= 0.2;
                        break;
                }
            }

            // 根据问题严重程度扣分
            foreach (var issue in report.Issues)
            {
                switch (issue.Severity)
                {
                    case IssueSeverity.Error:
                        report.OverallScore -= 1.5;
                        break;
                    case IssueSeverity.Warning:
                        report.OverallScore -= 0.8;
                        break;
                    case IssueSeverity.Info:
                        report.OverallScore -= 0.3;
                        break;
                }
            }

            report.OverallScore = Math.Max(0, Math.Round(report.OverallScore, 1));
        }

        private string ExtractMethodContent(string content, int startIndex)
        {
            var braceCount = 0;
            var inMethod = false;
            var methodContent = new System.Text.StringBuilder();

            for (int i = startIndex; i < content.Length; i++)
            {
                var c = content[i];
                methodContent.Append(c);

                if (c == '{')
                {
                    braceCount++;
                    inMethod = true;
                }
                else if (c == '}')
                {
                    braceCount--;
                    if (inMethod && braceCount == 0)
                    {
                        break;
                    }
                }
            }

            return methodContent.ToString();
        }

        private bool IsAcceptableSingleLetterVariable(string name)
        {
            var acceptable = new[] { "i", "j", "k", "x", "y", "z" }; // 循环变量
            return acceptable.Contains(name);
        }

        private string ApplyNamingConventions(string content, RefactoringResult result)
        {
            // 这里可以实现命名规范自动修复
            // 由于复杂性，这里只记录建议，实际修复需要人工干预
            result.Changes.Add(new RefactoringChange
            {
                Type = RefactoringType.NamingConvention,
                Description = "命名规范检查完成，请手动修复相关问题"
            });
            return content;
        }

        private string OrganizeImports(string content, RefactoringResult result)
        {
            // 实现using语句的自动整理
            var lines = content.Split('\n').ToList();
            var usingLines = new List<string>();
            var otherLines = new List<string>();
            var inUsingSection = true;

            foreach (var line in lines)
            {
                var trimmedLine = line.Trim();
                if (trimmedLine.StartsWith("using "))
                {
                    if (!inUsingSection)
                    {
                        inUsingSection = true;
                    }
                    usingLines.Add(line);
                }
                else
                {
                    if (inUsingSection && !string.IsNullOrWhiteSpace(trimmedLine))
                    {
                        inUsingSection = false;
                    }
                    otherLines.Add(line);
                }
            }

            // 按字母顺序排序using语句
            var sortedUsingLines = usingLines
                .OrderBy(line => line.Trim())
                .ToList();

            var organizedContent = string.Join("\n", sortedUsingLines) + "\n" + string.Join("\n", otherLines);

            if (organizedContent != content)
            {
                result.Changes.Add(new RefactoringChange
                {
                    Type = RefactoringType.CodeOrganization,
                    Description = "整理了using语句，按字母顺序排序"
                });
            }

            return organizedContent;
        }

        private string FixMagicNumbers(string content, RefactoringResult result)
        {
            // 简化的魔法数字修复演示
            var replacements = new Dictionary<string, string>
            {
                { " 60 ", " TimeSpan.FromSeconds(60) " },
                { " 3600 ", " TimeSpan.FromHours(1) " },
                { " 86400 ", " TimeSpan.FromDays(1) " },
                { " 100 ", " MaxRetryCount " },
                { " 500 ", " InternalServerError " }
            };

            var modifiedContent = content;
            var changes = new List<string>();

            foreach (var replacement in replacements)
            {
                if (modifiedContent.Contains(replacement.Key))
                {
                    modifiedContent = modifiedContent.Replace(replacement.Key, replacement.Value);
                    changes.Add($"替换魔法数字 {replacement.Key.Trim()} -> {replacement.Value.Trim()}");
                }
            }

            if (changes.Any())
            {
                result.Changes.Add(new RefactoringChange
                {
                    Type = RefactoringType.ExtractConstant,
                    Description = "替换魔法数字: " + string.Join(", ", changes)
                });
            }

            return modifiedContent;
        }

        private string ImproveExceptionHandling(string content, RefactoringResult result)
        {
            // 简化的异常处理改进
            var modifiedContent = content;
            var changes = 0;

            // 将空的catch块添加日志记录
            var emptyCatchPattern = @"(catch\s*\([^)]*\)\s*\{\s*\})";
            var emptyCatchReplacement = @"$1
            {
                _logger.LogError(ex, ""发生异常"");
                throw;
            }";

            var modifiedCount = 0;
            modifiedContent = Regex.Replace(modifiedContent, emptyCatchPattern, m =>
            {
                modifiedCount++;
                return emptyCatchReplacement;
            });

            if (modifiedCount > 0)
            {
                changes += modifiedCount;
                result.Changes.Add(new RefactoringChange
                {
                    Type = RefactoringType.ExceptionHandling,
                    Description = $"改进了 {modifiedCount} 个异常处理块"
                });
            }

            return modifiedContent;
        }

        private string OptimizeStringOperations(string content, RefactoringResult result)
        {
            // 简化的字符串操作优化
            var modifiedContent = content;
            var changes = 0;

            // 将简单的字符串拼接替换为字符串插值
            var stringConcatPattern = @"(\w+)\s*\+\s*""([^""]*)""";
            var stringConcatReplacement = @"$1 + ""$2""";

            // 这里只是示例，实际实现需要更复杂的逻辑
            if (modifiedContent.Contains("+\"") || modifiedContent.Contains("\"+"))
            {
                result.Changes.Add(new RefactoringChange
                {
                    Type = RefactoringType.StringOptimization,
                    Description = "检测到字符串拼接操作，建议使用字符串插值或StringBuilder"
                });
            }

            return modifiedContent;
        }

        private string GetRefactoringTypeName(RefactoringType type)
        {
            return type switch
            {
                RefactoringType.ExtractMethod => "方法提取",
                RefactoringType.ExtractConstant => "常量提取",
                RefactoringType.ExtractClass => "类提取",
                RefactoringType.NamingConvention => "命名规范",
                RefactoringType.CodeOrganization => "代码组织",
                RefactoringType.ExceptionHandling => "异常处理",
                RefactoringType.StringOptimization => "字符串优化",
                RefactoringType.PerformanceOptimization => "性能优化",
                _ => type.ToString()
            };
        }
    }

    #region 数据模型

    /// <summary>
    /// 重构报告
    /// </summary>
    public class RefactoringReport
    {
        public string FilePath { get; set; } = string.Empty;
        public string FileName { get; set; } = string.Empty;
        public DateTime AnalysisTime { get; set; }
        public double OverallScore { get; set; }
        public List<RefactoringSuggestion> Suggestions { get; set; } = new();
        public List<CodeIssue> Issues { get; set; } = new();
        public List<string> Errors { get; set; } = new();
        public List<CodeMetric> Metrics { get; set; } = new();
    }

    /// <summary>
    /// 重构建议
    /// </summary>
    public class RefactoringSuggestion
    {
        public RefactoringType Type { get; set; }
        public RefactoringPriority Priority { get; set; }
        public string Message { get; set; } = string.Empty;
        public string? Description { get; set; }
        public int LineNumber { get; set; }
    }

    /// <summary>
    /// 重构结果
    /// </summary>
    public class RefactoringResult
    {
        public string FilePath { get; set; } = string.Empty;
        public string OriginalContent { get; set; } = string.Empty;
        public string? RefactoredContent { get; set; }
        public bool Success { get; set; }
        public string? Message { get; set; }
        public List<RefactoringChange> Changes { get; set; } = new();
    }

    /// <summary>
    /// 重构变更
    /// </summary>
    public class RefactoringChange
    {
        public RefactoringType Type { get; set; }
        public string Description { get; set; } = string.Empty;
        public string? FilePath { get; set; }
    }

    /// <summary>
    /// 代码问题
    /// </summary>
    public class CodeIssue
    {
        public IssueSeverity Severity { get; set; }
        public string Message { get; set; } = string.Empty;
        public int LineNumber { get; set; }
    }

    /// <summary>
    /// 代码指标
    /// </summary>
    public class CodeMetric
    {
        public string Name { get; set; } = string.Empty;
        public object Value { get; set; } = string.Empty;
    }

    /// <summary>
    /// 重构选项
    /// </summary>
    public class RefactoringOptions
    {
        public bool CreateBackup { get; set; } = true;
        public bool FixNamingConventions { get; set; } = false;
        public bool OrganizeImports { get; set; } = false;
        public bool FixMagicNumbers { get; set; } = false;
        public bool ImproveExceptionHandling { get; set; } = false;
        public bool OptimizeStringOperations { get; set; } = false;
    }

    /// <summary>
    /// 重构类型
    /// </summary>
    public enum RefactoringType
    {
        Backup,
        ExtractMethod,
        ExtractConstant,
        ExtractClass,
        NamingConvention,
        CodeOrganization,
        ExceptionHandling,
        StringOptimization,
        PerformanceOptimization
    }

    /// <summary>
    /// 重构优先级
    /// </summary>
    public enum RefactoringPriority
    {
        Low,
        Medium,
        High
    }

    /// <summary>
    /// 问题严重程度
    /// </summary>
    public enum IssueSeverity
    {
        Info,
        Warning,
        Error
    }

    #endregion
}